<?php
/**
 * Copyright 2011  SURFfoundation
 * 
 * This file is part of ESCAPE.
 * 
 * ESCAPE is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * ESCAPE is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with ESCAPE.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * For more information:
 * http://escapesurf.wordpress.com/
 * http://www.surffoundation.nl/
 * 
 * Contact: d.vierkant@utwente.nl
 * 
 * @license http://www.gnu.org/licenses/gpl.html GNU GPLv3
 */
?>
<?php
/**
 * Begin openID login
 * 
 * Begin the openID login process.
 * Adds errors to $this->requestAttributes['errorMessages'].
 * On failure, jumps to the action identified by $_REQUEST['onFailure'].
 * After completion of the remote openID login, the action CompleteOpenIdLogin will complete the process.
 */
class escape_repositoryui_action_BeginOpenIdLogin extends escape_repositoryui_Action
{
	public function handleRequest()
	{
		// PHP4 code in the php-openid library causes a lot of warnings
		error_reporting(E_ALL ^ E_COMPILE_WARNING ^ E_NOTICE ^ E_WARNING ^ E_DEPRECATED);
		require_once("php-openid-2/include.php");
	
		session_start();
	
		/* @var $repository escape_repository_Repository */
		$repository =& $this->requestAttributes['repository'];
		/* @var $repositoryUi escape_repositoryui_RepositoryUi */
		$repositoryUi =& $this->requestAttributes['repositoryUi'];
		
		// check if OpenID is enabled
		if(!$repository->config['localauthn_enabled'] || !$repository->config['signup_enabled'] || !$repository->config['openidauthn_enabled'])
		{
			// openid is disabled
			$repositoryUi->displayErrorPage('OpenID is disabled.');
			return null;
		}
		
		// get the error messages queue
		$errorMessages =& $this->requestAttributes['errorMessages'];
		if(!isset($errorMessages))
		{
			$errorMessages = array();
		}
		
		$onSuccess = $_REQUEST['onSuccess'];
		if(!isset($onSuccess))
		{
			print "Invalid request";
			return null;
		}
		$onFailure = $_REQUEST['onFailure'];
		if(!isset($onFailure))
		{
			print "Invalid request";
			return null;
		}
		
		// build a return to URL
		$requestParameters = array_merge($_GET, $_POST);
		unset($requestParameters['action']);
		unset($requestParameters['openid']);
		$returnTo = $repository->config['server_url'] . '/completeOpenIdLogin?' . http_build_query($requestParameters);
		
		$trustRoot = $repository->config['server_url'];
		
		// get the openID file store
		$openIdStorePath = $repository->config['openid_store_path'] . $repository->config['virtualhost'] . '/';
		$store = new Auth_OpenID_FileStore($openIdStorePath);
		
		// get the openID consumer
		$consumer = new Auth_OpenID_Consumer($store);
		
		// begin OpenID login
		$openId = null;
		if(isset($_REQUEST['openid']))
		{
			$openId = $_REQUEST['openid'];
		}
		
		if($openId === null || $openId === '')
		{
			$errorMessages[] = 'Please provide a valid OpenID';
		}
		else
		{
			// begin the OpenID authentication process
			$authRequest = $consumer->begin($openId);
			
			// No auth request means we can't begin OpenID.
			if(!$authRequest)
			{
				$errorMessages[] = 'Authentication error: not a valid OpenID';
			}
			else
			{
//				$sregRequest = Auth_OpenID_SRegRequest::build(
//															 //	Required
//															 array(),
//															 //	Optional
//															 array('nickname', 'fullname', 'email')
//															);
//				if($sregRequest)
//				{
//					$authRequest->addExtension($sregRequest);
//				}
		
				$axRequestProfileData = array(
					'email'		=> 'http://schema.openid.net/contact/email',
					'firstname'	=> 'http://schema.openid.net/namePerson/first',
					'lastname'	=> 'http://schema.openid.net/namePerson/last',
					'firstnameax'	=> 'http://axschema.org/namePerson/first',
					'lastnameax'	=> 'http://axschema.org/namePerson/last',
				);
				
				$axRequest	= new Auth_OpenID_AX_FetchRequest();
				if($axRequest)
				{
					foreach($axRequestProfileData as $alias => $url)
					{
						$axRequest->add(Auth_OpenID_AX_AttrInfo::make($url, 1, true, $alias));
					}
					$authRequest->addExtension($axRequest);
				}
				
				// Redirect the user to the OpenID server for authentication.
				// Store the token for this authentication so we can verify the
				// response
		
				// For OpenID 1, send a redirect.  For OpenID 2, use a Javascript
				// form to send a POST request to the server
				if($authRequest->shouldSendRedirect())
				{
					$redirectUrl = $authRequest->redirectURL($trustRoot, $returnTo);
		
					// If the redirect URL can't be built, display an error
					// message.
					if (Auth_OpenID::isFailure($redirectUrl))
					{
						$errorMessages[] = 'Could not redirect to server: ' . $redirectUrl->message;
					}
					else{
						// Send redirect
						header("Location: " . $redirectUrl);

						return null;
					}
				}
				else
				{
					// Generate form markup and render it.
					$form_id = 'openid_message';
					$formHtml = $authRequest->htmlMarkup($trustRoot, $returnTo, false, array('id' => $form_id));
					
					// Display an error if the form markup couldn't be generated;
					// otherwise, render the HTML.
					if(Auth_OpenID::isFailure($formHtml))
					{
						$errorMessages[] = 'Could not redirect to server: ' . $formHtml->message;
					}
					else
					{
						// print OpenID redirect form
						print $formHtml;

						return null;
					}
				}
			}
		}
		
		$this->requestAttributes['errorMessages'] =& $errorMessages;
		
		return 'action::' . $onFailure;
	}
}